using System;
using System.Collections.Generic;
using System.Threading;

namespace mebc4.tablebased.synchronous
{
    class MebcRuntime
    {
        private readonly Dictionary<string, List<string>> mappings = new Dictionary<string, List<string>>();
        private readonly Dictionary<string, Delegate> inputPins = new Dictionary<string, Delegate>();

        public void Map(string outputPinName, string inputPinName)
        {
            List<string> mapping;
            if (!mappings.TryGetValue(outputPinName, out mapping))
            {
                mapping = new List<string>();
                mappings.Add(outputPinName, mapping);
            }

            mapping.Add(inputPinName);
        }


        public void Reg<T>(string inputPinName, Action<T> processor)
        {
            inputPins.Add(inputPinName, processor);
        }


        public void Send(string outputPinName, object message)
        {
            Console.WriteLine("   send({0}, {1}), thread {2}", outputPinName, message!=null ? message.GetType().Name : "NULL", Thread.CurrentThread.GetHashCode());

            var mapping = mappings[outputPinName];
            mapping.ForEach(m =>
                                {
                                    var p = inputPins[m];
                                    p.DynamicInvoke(message);
                                });
        }
    }
}